/*******************************************************************************
 * Copyright (c) 2011 TXT e-solutions SpA
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the research area ICT-2009.1.3
 * Internet of Things and enterprise environments.
 *
 *
 * Authors:
 *     Cristoforo Seccia (TXT e-solutions SpA)
 *
 * Contributors:
 *      Domenico Rotondi (TXT e-solutions SpA)
 *******************************************************************************/
package it.txt.access.capability.wizard;

import java.util.HashMap;
import javax.swing.JOptionPane;

/**
 *
 * @author Cristoforo Seccia (TXT e-solutions SpA)
 */
public class WizardController {

    private WizardPanelDescriptor currentPanel;
    private String previousPanelIdentifier;
    private HashMap panelHashmap;
    private Wizard myWizard;

    protected WizardController(Wizard wizard) {
        panelHashmap = new HashMap();
        myWizard = wizard;
    }

    protected WizardPanelDescriptor getCurrentPanelDescriptor() {
        return currentPanel;
    }

    protected void registerPanel(String id, WizardPanelDescriptor descriptor) {
        panelHashmap.put(id, descriptor);
        descriptor.getPanelController();
    }

    protected boolean registerCurrentPanel(String id) throws WizardException {
        WizardPanelDescriptor nextPanel =
                (WizardPanelDescriptor) panelHashmap.get(id);
        if (nextPanel == null) {
            throw new WizardException("Wizard Panel not found.");
        }
        currentPanel = nextPanel;
        return true;
    }

    protected void setCurrentPanel(String id, String occurredAction) {
        if (occurredAction.equals(Wizard.START_ACTION)) {
            setStartingPanel(id);
        } else if (occurredAction.equals(Wizard.BACK_ACTION)) {
            setBackwardPanel(id);
        } else if (occurredAction.equals(Wizard.NEXT_ACTION)) {
            setForwardPanel(id);
        }
    }

    private void setStartingPanel(String startPanelId) {
        try {
            // Set the Current panel as the first.
            registerCurrentPanel(startPanelId);
            // The previous panel is the same as the welcome panel.
            previousPanelIdentifier = getCurrentPanelDescriptor().getIdentifier();
            // Tell the welcome panel that is shown.
            getCurrentPanelDescriptor().getPanelController().displayingPanel();
            //Tell the wizard to show the current panel label.
            myWizard.setCurrentWizardLabel(0,0);
        } catch (WizardException ex) {
            JOptionPane.showMessageDialog(myWizard, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        } 
    }

    private void setBackwardPanel(String backPanelId) {
        try {
            //If the back panel ID is undefined then use the previous panel ID.
            if (backPanelId.equals(WizardPanelDescriptor.UNKNOW_PANEL_ID)) {
                backPanelId = previousPanelIdentifier;
            }
            //Recover the current panel ordinal number.
            int currentPanelOrdinalNumber = getCurrentPanelDescriptor().getWizardPanelOrdinalNumber();
            //Register the current panel as the back panel.
            registerCurrentPanel(backPanelId);
            // Tell current panel that is shown.
            getCurrentPanelDescriptor().getPanelController().displayingPanel();
            //Recover the back panel id.
            int backPanelOrdinalNumber = getCurrentPanelDescriptor().getWizardPanelOrdinalNumber();
            //Tell the wizard to show the current panel label.
            myWizard.setCurrentWizardLabel(currentPanelOrdinalNumber, backPanelOrdinalNumber);
        }
        catch (WizardException ex) {
            JOptionPane.showMessageDialog(myWizard, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void setForwardPanel(String nextPanelId) {
        try {
            //Recover the current panel descriptor.
            WizardPanelDescriptor currentPanelDescriptor = getCurrentPanelDescriptor();
            //Recover the current panel ordinal number.
            int currentPanelOrdinalNumber = currentPanelDescriptor.getWizardPanelOrdinalNumber();
            //Check if the current panel can be closed.
            if (currentPanelDescriptor.getPanelController().aboutToHidePanel()) {
                //Recover the forkward object.
                Object fo = currentPanelDescriptor.getPanelController().getForwardObject();
                //Temporarily set the next panel by using the received identifier.
                registerCurrentPanel(nextPanelId);
                //Set the backward object to the next panel, as the forward object.
                getCurrentPanelDescriptor().getPanelController().setBackwardObject(fo);
                //Check if the next panel can be opened.
                if (getCurrentPanelDescriptor().getPanelController().aboutToDisplayPanel()) {
                    //Ok, now get user confirmation
                    if (getUserConfirmation(currentPanelDescriptor)) {
                        //Set the previouse panel ID as the current but only if the current panel knows is backward panel
                        setPreviousPanelIfExists(currentPanelDescriptor);
                        //Display the next panel and return;
                        getCurrentPanelDescriptor().getPanelController().displayingPanel();
                        //Recover the next panel ordinal number
                        int nextPanelOrdinalNumber = getCurrentPanelDescriptor().getWizardPanelOrdinalNumber();
                        //Tell the wizard to update the showing panel label.
                        myWizard.setCurrentWizardLabel(currentPanelOrdinalNumber,nextPanelOrdinalNumber);
                        //Return so as to display the next panel.
                        return;
                    }
                }
                //The next panel cannot be opened or the user wants to review the form so rollback to the current panel.
                registerCurrentPanel(currentPanelDescriptor.getIdentifier());
            }
        }
        catch (WizardException ex) {
            JOptionPane.showMessageDialog(myWizard, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void setPreviousPanelIfExists(WizardPanelDescriptor currentPanelDescriptor){
        if(currentPanelDescriptor.getBackIdentifier() == null){
            return;
        }
        if((currentPanelDescriptor.getBackIdentifier().equals(WizardPanelDescriptor.UNKNOW_PANEL_ID))){
            return;
        }
        previousPanelIdentifier = currentPanelDescriptor.getIdentifier();
    }

    private boolean getUserConfirmation(WizardPanelDescriptor descriptor) {
        boolean confirm = true;
        if (descriptor.isUserConfiramtionRequired()) {
            Object[] options = {"Yes, please", "No, thanks"};
            int resp = JOptionPane.showOptionDialog(myWizard,
                    "Do you want to proceed?",
                    "Create your Access Policy",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    options,
                    options[0]);
            confirm = (resp == JOptionPane.YES_OPTION ? true : false);
        }
        return confirm;
    }
}
